/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file    usart.c
 * @brief   This file provides code for the configuration
 *          of the USART instances.
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2025 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"
#include "stdio.h"
#include "stm32f4xx_hal_gpio.h"
#include "stm32f4xx_hal_gpio_ex.h"
#include "stm32f4xx_hal_rcc.h"
#include "stm32f4xx_hal_rcc_ex.h"
#include <stdarg.h>
#include <string.h>


/* USER CODE BEGIN 0 */
char *ser3_TXBuffP;
char ser3_RB[ser3_RD_BUFFMAX]; // 串口3接收缓冲区
char ser3_TB[ser3_TX_BUFFMAX]; // 串口3发送缓冲区
unsigned char ser3_WrFlag1;
unsigned char ser3_WrFlag2;
unsigned char ser3_RdFlag;
unsigned int ser3_RdNum;  // 接收数据个数
unsigned int ser3_TxNum;  // 发送数据个数
unsigned int ser3_TxNum1; // 发送数据个数
unsigned char ser3_RdTime;
unsigned char ser3_RdStep;
static uint8_t ser3_rx_data;
/* USER CODE END 0 */

UART_HandleTypeDef huart3;

/* USART3 init function */

void MX_USART3_UART_Init(void) {
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* 使能串口3和GPIOC时钟 */
  __HAL_RCC_USART3_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();

  /* 配置USART3 Tx (PC10) 和 Rx (PC11) 引脚 */
  GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /* 初始化串口3 */
  huart3.Instance = USART3;
  huart3.Init.BaudRate = 9600;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart3) != HAL_OK) {
    Error_Handler();
  }

  /* NVIC配置 */
  HAL_NVIC_SetPriority(USART3_IRQn, 3, 0);
  HAL_NVIC_EnableIRQ(USART3_IRQn);

  /* 使能串口3接收中断 */
  HAL_UART_Receive_IT(&huart3, &ser3_rx_data, 1);

  ser3_RdFlag = 0;
  ser3_WrFlag1 = 0;
  ser3_RdStep = 0;
  memset(ser3_RB, 0x00, ser3_RD_BUFFMAX);
  memset(ser3_TB, 0x00, ser3_TX_BUFFMAX);
}

/**
 * @brief 向串口发送一个字符串，strlen为该字符串长度
 *
 * @param ser3buff
 * @param TX_Num
 */
void ser3_Write(char *ser3buff, u16 TX_Num) {
  if (ser3_WrFlag1 == 0 && TX_Num < ser3_TX_BUFFMAX) {
    HAL_UART_Transmit_IT(&huart3, (uint8_t *)ser3buff, TX_Num);
  }
  ser3_RdFlag = 0;
}
/**
 * @brief 串口发送日志
 *
 * @param format
 * @param ...
 */
void ser3_send_log(const char *format, ...) {
  char buffer[256]; // 定义一个足够大的缓冲区来存储格式化后的字符串
  va_list args;
  va_start(args, format);
  int len = vsnprintf(buffer, sizeof(buffer), format, args);
  va_end(args);
  if (len > 0) {
    ser3_Write(buffer, len);
  }
}
/**
 * @brief 接收中断回调函数
 *
 * @param huart
 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
  if (huart->Instance == USART3) {
    HAL_UART_Receive_IT(&huart3, &ser3_rx_data, 1);
    ser3_RdTime = 0;

    if (ser3_RdFlag == 0) {
      if (ser3_RdStep == 0) {
        ser3_RdStep = 1;
        ser3_RdNum = 0;
      }
      ser3_RB[ser3_RdNum] = ser3_rx_data;
      ser3_RdNum++;
    }
  }
}
/**
 * @brief 发送中断回调函数
 *
 * @param huart
 */
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
  if (huart->Instance == USART3) {
    if (ser3_WrFlag1 == 1) {
      if (ser3_TxNum < ser3_TxNum1) {
        // 继续发送下一个字节
        HAL_UART_Transmit_IT(&huart3, (uint8_t *)&ser3_TXBuffP[ser3_TxNum], 1);
        ser3_TxNum++;
      } else {
        // 发送完成
        ser3_TxNum = 0;
        ser3_TxNum1 = 0;
        ser3_WrFlag1 = 0;
        __HAL_UART_DISABLE_IT(&huart3, UART_IT_TXE); // 禁用发送中断
      }
    } else {
      ser3_WrFlag1 = 0;
      __HAL_UART_DISABLE_IT(&huart3, UART_IT_TXE); // 禁用发送中断
    }
  }
}
// void USART3_IRQHandler(void) {
//   // 调用HAL库的中断处理函数
//   HAL_UART_IRQHandler(&huart3);
// }
void HAL_UART_MspInit(UART_HandleTypeDef *uartHandle) {

  GPIO_InitTypeDef GPIO_InitStruct;
  if (uartHandle->Instance == USART3) {
    /* USART3 clock enable */
    __HAL_RCC_USART3_CLK_ENABLE();

    __HAL_RCC_GPIOC_CLK_ENABLE();
    /**USART3 GPIO Configuration
    PC10     ------> USART3_TX
    PAC11    ------> USART3_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* USART3 interrupt Init */
    HAL_NVIC_SetPriority(USART3_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(USART3_IRQn);
  }
}

void HAL_UART_MspDeInit(UART_HandleTypeDef *uartHandle) {

  if (uartHandle->Instance == USART3) {
    /* Periphera3 clock disable */
    __HAL_RCC_USART3_CLK_DISABLE();

    /**USART3 GPIO Configuration
    PC10     ------> USART3_TX
    PC11    ------> USART3_RX
    */
    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10 | GPIO_PIN_11);

    /* USART3 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USART3_IRQn);
  }
}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */
